/*
 * @(#)EncytUtils.java 2009-7-3
 * 
 * Copyright 5jxiang . All rights reserved.
 */
package com.jz.util;

import java.security.Provider;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import org.apache.commons.codec.binary.Base64;

/**
 * <p>
 * <a href="EncytUtils.java.html"><i>View Source</i></a>
 * </p>
 *
 * @author 5jxiang
 * @version $Id$
 */
public class EncryptUtils {
	 private static String CryptAlgorithm = "DESede/CBC/PKCS5Padding";
	 private static String KeyAlgorithm = "DESede";
	 public static String defaultIV = "8, 7, 9, 6, 10, 5, 11, 4";
	
	 public static byte[] defaultIVBytes = {8, 7, 9, 6, 10, 5, 11, 4};
    /**
     * 加密算法
     * @param password  等待加密的密码
     * @return          加密以后的密码
     * @throws Exception
     */
	 
	public static byte[] getIvFromIvstring(String str) {
		if (str == null || str.length() < 15) {
			return defaultIVBytes;
		}
		String []strs = str.split(",");
		if (strs == null || strs.length != 8) {
			return defaultIVBytes;
		}
		byte [] bs = new byte[8];
		for (int i = 0; i < strs.length; i++) {
			try {
				bs[i] = (byte)Integer.parseInt(strs[i]);
			} catch (Exception e) {
				return defaultIVBytes;
			}
		}
		return bs;
	}
	 
    public static byte[] encrypt(byte[] data, byte[] key, byte[]iv)
    {
        byte[] encrypted_pwd = null;

        try
        {
        	
        	try{ 
        		Cipher c = Cipher.getInstance(KeyAlgorithm); 
        		}
            catch (Exception e)
            {
                System.err.println("Installling SunJCE provider.");
                Provider sunjce = new com.sun.crypto.provider.SunJCE();
                Security.addProvider(sunjce);
            }


            // 为上一密钥创建一个指定的 DESSede key
            DESedeKeySpec spec = new DESedeKeySpec(key);

            // 得到 DESSede keys
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KeyAlgorithm);

            // 生成一个 DESede 密钥对象
            SecretKey theKey = keyFactory.generateSecret(spec);
        	
        	Cipher cipher  = Cipher.getInstance(CryptAlgorithm);
        	
        	if (iv == null || iv.length != 8) {
        		iv = defaultIVBytes;
        	}
        	IvParameterSpec ivParameters = 
                new IvParameterSpec(iv);
        	
            // 以加密模式初始化密钥
            cipher.init(Cipher.ENCRYPT_MODE,theKey, ivParameters);


            // 加密密码
            encrypted_pwd = cipher.doFinal(data);

        }
        catch(Exception ex)
        {
            // 记录加密错误
        }

        return encrypted_pwd;
    }

    /**
     * 解密算法
     * @param password  加过密的密码
     * @return          解密后的密码
     */
    public static byte[] decrypt(byte[] data, byte[] key, byte[]iv)
    {
    	
    	byte[] encrypted_pwd = null;

        try
        {
        	
        	try{ 
        		Cipher c = Cipher.getInstance(KeyAlgorithm); 
        		}
            catch (Exception e)
            {
                System.err.println("Installling SunJCE provider.");
                Provider sunjce = new com.sun.crypto.provider.SunJCE();
                Security.addProvider(sunjce);
            }


            // 为上一密钥创建一个指定的 DESSede key
            DESedeKeySpec spec = new DESedeKeySpec(key);

            // 得到 DESSede keys
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KeyAlgorithm);

            // 生成一个 DESede 密钥对象
            SecretKey theKey = keyFactory.generateSecret(spec);
        	
        	Cipher cipher  = Cipher.getInstance(CryptAlgorithm);
        	
        	if (iv == null || iv.length != 8) {
        		iv = defaultIVBytes;
        	}
        	IvParameterSpec ivParameters = 
                new IvParameterSpec(iv);
        	
            // 以加密模式初始化密钥
            cipher.init(Cipher.DECRYPT_MODE,theKey, ivParameters);


            // 加密密码
            encrypted_pwd = cipher.doFinal(data);

        }
        catch(Exception ex)
        {
            // 记录加密错误
        }
        
        return encrypted_pwd;
       
    }
    
    public static byte[] Base64Encode(byte b[])
    throws Exception
    {
    	return Base64.encodeBase64(b);
    }

    public static byte[] Base64Decode(byte b[])
    throws Exception
    {
    	return Base64.decodeBase64(b);
    }
    
    public static byte[]DESBase64Encode(byte[] data, byte[] key, byte[] iv) {
    	byte [] bs = encrypt(data, key, iv);
    	try {
			return Base64Encode(bs);
		} catch (Exception e) {
			return null;
		}
    }
    
    public static byte[]DESBase64Decode(byte[] data, byte[] key, byte[] iv) {
    	byte[] bs;
		try {
			bs = Base64Decode(data);
		} catch (Exception e) {
			return null;
		};
    	
		return decrypt(bs, key, iv);
		
    }
    
    public static String DESBase64Encode(String data, String key, String iv) {
    	byte [] bs = encrypt(data.getBytes(), key.getBytes(), getIvFromIvstring(iv));
    	try {
    		
			bs = Base64Encode(bs);
			if (bs != null) {
				
				return new String(bs);
			}
		} catch (Exception e) {
			return null;
		}
		return null;
    }
    
    public static String DESBase64Decode(String data, String key, String iv) {
    	byte[] bs;
		try {
			bs = Base64Decode(data.getBytes());
			
		} catch (Exception e) {
			return null;
		};
		if (bs == null)
			return null;
		bs = decrypt(bs, key.getBytes(), getIvFromIvstring(iv));
		if (bs != null) {
			
			return new String(bs);
		}
		return null;
		
    }
    
    public static void main(String []args) {
    	String data = "e866c47b7a7c459d8e2e6f83d92b4f9b";
    	String key = "ce92f37bfe5e41a6a4e49c53828b69aa";
    	String iv = "8, 7, 9, 6, 10, 5, 11, 4";
    	
    	String str = EncryptUtils.DESBase64Encode(data, key, iv);
    	
    	str = EncryptUtils.DESBase64Decode(str, key, iv);
    	
    }
}
